package com.ysynzehao.db;

import com.ysynzehao.dao.utils.BaseRepositoryFactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.Database;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

/**
 * niuzehao
 * 2018/12/7 9:30.
 */
@Configuration
@AutoConfigureAfter(DataSourceConfiguration.class)
@EnableJpaRepositories(basePackages = {"com.ysynzehao.dao"},
        repositoryFactoryBeanClass = BaseRepositoryFactoryBean.class)
public class DbConfiguration {

    private AbstractRoutingDataSource dynamicDataSource;

    @Autowired
    @Qualifier("masterDataSerouce")
    private DataSource masterDataSerouce;

    @Autowired
    @Qualifier("slaverDataSerouce")
    private DataSource slaverDataSerouce;

    @Bean
    public AbstractRoutingDataSource dynamicDataSource() {
        dynamicDataSource = new DynamicDataSource();
        Map<Object, Object> targetDataSources = new HashMap<>();
        targetDataSources.put(DbContextHolder.DbType.MASTER.name(), masterDataSerouce);
        targetDataSources.put(DbContextHolder.DbType.SLAVE.name(), slaverDataSerouce);
        dynamicDataSource.setTargetDataSources(targetDataSources);
        dynamicDataSource.setDefaultTargetDataSource(masterDataSerouce);
        return dynamicDataSource;
    }

    @Bean
    @Primary
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(AbstractRoutingDataSource dynamicDataSource) {
        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        vendorAdapter.setDatabase(Database.MYSQL);
        //是否生成表
        vendorAdapter.setGenerateDdl(true);
//        vendorAdapter.getJpaPropertyMap().put("hibernate.implicit_naming_strategy", "org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy");
//        vendorAdapter.getJpaPropertyMap().put("hibernate.physical_naming_strategy", "org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy");
        //是否显示sql语句
        vendorAdapter.setShowSql(true);
        Map<String, Object> properties2 = new HibernateProperties().determineHibernateProperties(new HashMap<>(), new HibernateSettings());
        vendorAdapter.getJpaPropertyMap().putAll(properties2);
        LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
        factory.setJpaVendorAdapter(vendorAdapter);
        factory.setJpaPropertyMap(properties2);
        //配置扫描的位置
        factory.setPackagesToScan("com.ysynzehao.bean");
        // 这个数据源设置为代理的数据源，----这是关键性配置！！！
        factory.setDataSource(dynamicDataSource);
        return factory;
    }

    @Primary
    @Bean(name = "transactionManager")
    public JpaTransactionManager transactionManager(LocalContainerEntityManagerFactoryBean entityManagerFactory, AbstractRoutingDataSource dynamicDataSource) {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setDataSource(dynamicDataSource);
        transactionManager.setEntityManagerFactory(entityManagerFactory.getObject());
        return transactionManager;
    }
}
